<!DOCTYPE html>
<html lang="en">
<head>
    
    <meta charset="utf-8">
    <title>Home - Aliwork helper</title>
    
    <meta name="description" content="宜搭前端 JS 工具代码库" />
    
        <meta name="keywords" content="Aliwork 宜搭 工具库" />
        <meta name="keyword" content="Aliwork 宜搭 工具库" />
    
    
    
    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
    <script src="scripts/nav.js" defer></script>
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav >
    
    <input type="text" id="nav-search" placeholder="Search" />
    
    
    <h2><a href="index.html">Home</a></h2><h2><a href="https://github.com/hackingzhang/aliwork-helper" target="_blank" class="menu-item" >Github</a></h2><h2><a href="https://gitee.com/hexzhangshuai/aliwork-helper" target="_blank" class="menu-item" >Gitee码云</a></h2><h2><a href="https://docs.aliwork.com/docs/developer/api/about" target="_blank" class="menu-item" >宜搭开放API</a></h2><h3>Modules</h3><ul><li><a href="module-DataLinkage.html">DataLinkage</a><ul class='methods'><li data-type='method'><a href="module-DataLinkage.html#.dataLinkage">dataLinkage</a></li><li data-type='method'><a href="module-DataLinkage.html#.dataLinkageSubform">dataLinkageSubform</a></li><li data-type='method'><a href="module-DataLinkage.html#~resolveConditionMap">resolveConditionMap</a></li></ul></li><li><a href="module-DataSource.html">DataSource</a><ul class='methods'><li data-type='method'><a href="module-DataSource.html#.deleteFormData">deleteFormData</a></li><li data-type='method'><a href="module-DataSource.html#.executeTask">executeTask</a></li><li data-type='method'><a href="module-DataSource.html#.fetchSubformDatas">fetchSubformDatas</a></li><li data-type='method'><a href="module-DataSource.html#.fetchSubformDatasAll">fetchSubformDatasAll</a></li><li data-type='method'><a href="module-DataSource.html#.getFormData">getFormData</a></li><li data-type='method'><a href="module-DataSource.html#.getOperationRecords">getOperationRecords</a></li><li data-type='method'><a href="module-DataSource.html#.saveFormData">saveFormData</a></li><li data-type='method'><a href="module-DataSource.html#.searchFormDataIds">searchFormDataIds</a></li><li data-type='method'><a href="module-DataSource.html#.searchFormDataIdsAll">searchFormDataIdsAll</a></li><li data-type='method'><a href="module-DataSource.html#.searchFormDatas">searchFormDatas</a></li><li data-type='method'><a href="module-DataSource.html#.searchFormDatasAll">searchFormDatasAll</a></li><li data-type='method'><a href="module-DataSource.html#.startInstance">startInstance</a></li><li data-type='method'><a href="module-DataSource.html#.updateFormData">updateFormData</a></li></ul></li><li><a href="module-Field.html">Field</a><ul class='methods'><li data-type='method'><a href="module-Field.html#.activateTabItems">activateTabItems</a></li><li data-type='method'><a href="module-Field.html#.fieldToString">fieldToString</a></li><li data-type='method'><a href="module-Field.html#.fieldValueDiff">fieldValueDiff</a></li><li data-type='method'><a href="module-Field.html#.fieldValueEqualSingle">fieldValueEqualSingle</a></li><li data-type='method'><a href="module-Field.html#.generateAssociationFormFieldData">generateAssociationFormFieldData</a></li><li data-type='method'><a href="module-Field.html#.generateDptFieldData">generateDptFieldData</a></li><li data-type='method'><a href="module-Field.html#.generateEmployeeFieldData">generateEmployeeFieldData</a></li><li data-type='method'><a href="module-Field.html#.getFieldDataTypeById">getFieldDataTypeById</a></li><li data-type='method'><a href="module-Field.html#.getFieldTypeById">getFieldTypeById</a></li><li data-type='method'><a href="module-Field.html#.mergeTo">mergeTo</a></li><li data-type='method'><a href="module-Field.html#.syncTo">syncTo</a></li></ul></li><li><a href="module-Subform.html">Subform</a><ul class='methods'><li data-type='method'><a href="module-Subform.html#.associateForm2Subform">associateForm2Subform</a></li><li data-type='method'><a href="module-Subform.html#.sum2Main">sum2Main</a></li><li data-type='method'><a href="module-Subform.html#~resolveFieldMaps">resolveFieldMaps</a></li></ul></li><li><a href="module-UI.html">UI</a><ul class='methods'><li data-type='method'><a href="module-UI.html#.dialog">dialog</a></li><li data-type='method'><a href="module-UI.html#.hijackSubmit">hijackSubmit</a></li><li data-type='method'><a href="module-UI.html#.loading">loading</a></li></ul></li><li><a href="module-Utils.html">Utils</a><ul class='methods'><li data-type='method'><a href="module-Utils.html#.dateTimeFormat">dateTimeFormat</a></li><li data-type='method'><a href="module-Utils.html#.generateRandomId">generateRandomId</a></li><li data-type='method'><a href="module-Utils.html#.isEmpty">isEmpty</a></li><li data-type='method'><a href="module-Utils.html#.retry">retry</a></li><li data-type='method'><a href="module-Utils.html#.round">round</a></li><li data-type='method'><a href="module-Utils.html#.sleep">sleep</a></li></ul></li></ul><h3>Classes</h3><ul><li><a href="FieldChangeLogger.html">FieldChangeLogger</a><ul class='methods'><li data-type='method'><a href="FieldChangeLogger.html#change">change</a></li><li data-type='method'><a href="FieldChangeLogger.html#clear">clear</a></li><li data-type='method'><a href="FieldChangeLogger.html#format">format</a></li></ul></li><li><a href="module-Subform-Subform.html">Subform</a><ul class='methods'><li data-type='method'><a href="module-Subform-Subform.html#getDatas">getDatas</a></li><li data-type='method'><a href="module-Subform-Subform.html#getFormGroupId">getFormGroupId</a></li><li data-type='method'><a href="module-Subform-Subform.html#getFormGroupIds">getFormGroupIds</a></li><li data-type='method'><a href="module-Subform-Subform.html#getIndex">getIndex</a></li><li data-type='method'><a href="module-Subform-Subform.html#getInstance">getInstance</a></li><li data-type='method'><a href="module-Subform-Subform.html#getItem">getItem</a></li><li data-type='method'><a href="module-Subform-Subform.html#setDatas">setDatas</a></li><li data-type='method'><a href="module-Subform-Subform.html#summary">summary</a></li><li data-type='method'><a href="module-Subform-Subform.html#updateItem">updateItem</a></li></ul></li></ul>
    
</nav>

<div id="main">
    

    



    


    <section class="package">
        <h3> </h3>		
    </section>









    



    <section class="readme usertext">
        <article><h1>Aliwork-helper: 宜搭前端 JS 工具代码库</h1>
<p>本仓库提供了了一些钉钉宜搭前端 JS 开发常用的工具方法，包括跨应用数据源 API 封装、UI 工具函数、字段值处理、常用场景封装等，旨在提高宜搭前端开发效率。</p>
<h2>文档</h2>
<p>文档使用 JSDoc 生成，可以在当前仓库的 docs 目录下只找到，或者<a href="https://hackingzhang.github.io/aliwork-helper/">查看在线文档</a>。</p>
<h2>如何使用</h2>
<p><strong>推荐使用<a href="#%E4%BB%A3%E7%A0%81%E6%A8%A1%E6%9D%BF">代码模板</a>来组织宜搭 JS 代码</strong></p>
<ol>
<li>
<h2>引入 JS 库</h2>
<p><strong>我们不提供本库的 CDN 或者公共访问托管，请自行解决托管问题</strong><br>
在 didMount 函数中加入以下代码来加载 Aliwork-helper：</p>
<pre class="prettyprint source lang-Javascript"><code>this.utils.loadScript(&quot;url-to-aliwork-helper.min.js&quot;).then(() => {
   // 加载完成后会暴露 Awh 全局变量，所有方法函数/类均可以通过 Awh.xxx 访问
   console.log(Awh);
   Awh.dialog(this, &quot;show&quot;， &quot;提示&quot;, &quot;加载完成&quot;);
});
</code></pre>
<p>一般情况下，只需要在 didMount 中加载一次即可全局访问 Awh。但是，如果有以下情况，则建议像上面那样先加载再调用，以免因为库文件未加载完成而报错。</p>
<ul>
<li>代码逻辑需要在页面加载完成后立即调用本库做一些事情</li>
<li>组件设置了除“自定义”之外的默认值（通过快捷配置、公式或者数据联动），同时设置了 onChange 事件，且需要在事件回调中调用本库</li>
</ul>
</li>
<li>
<h2>复制源码到宜搭 JS 面板</h2>
<p>找到需要的方法函数源代码，然后将整个函数定义复制到宜搭设计器动作面板。<br>
在文档中可以通过下面的方法找到函数源码：<br>
每一个方法参数列表下方都有一个 View Source 按钮，后面跟着方法所在的源文件和在源文件中的行数，如下图：<br>
<img src="https://hackingzhang.github.io/aliwork-helper/assets/how-to-locate-source-code.png" alt="定位源代码"><br>
点击行数即可跳转到源码页面。<br>
<img src="https://hackingzhang.github.io/aliwork-helper/assets/locate-source-code.png" alt="定位源代码"></p>
</li>
</ol>
<h2>代码模板</h2>
<h3>宜搭 JS 模板</h3>
<p>在使用宜搭 JS 实现复杂业务场景时，一不小心就会写出几千行的代码，而宜搭 JS 不支持模块化（当然，
可以引入外部 JS），所以如何在单个文件内组织业务代码对应用的可维护性至关重要。推荐使用下面的模板来组织宜搭 JS 代码。</p>
<pre class="prettyprint source lang-Javascript"><code>/**
* 尊敬的用户，你好：页面 JS 面板是高阶用法，一般不建议普通用户使用，如需使用，请确定你具备研发背景，能够自我排查问题。当然，你也可以咨询身边的技术顾问或者联系宜搭平台的技术支持获得服务（可能收费）。
* 我们可以用 JS 面板来开发一些定制度高功能，比如：调用阿里云接口用来做图像识别、上报用户使用数据（如加载完成打点）等等。
* 你可以点击面板上方的 「使用帮助」了解。
*/

/* -------------------------------------------------------------------------- */
/*                                  通用工具函数/类                                  */
/* -------------------------------------------------------------------------- */



/* -------------------------------------------------------------------------- */
/*                                   具体业务代码                                   */
/* -------------------------------------------------------------------------- */


/* ------------------ 建议将处理同一业务逻辑的代码组织在一起，不同业务逻辑之间用单行注释块分隔，就像这样 ------------------ */



/* -------------------------------------------------------------------------- */
/*                                  生命周期钩子函数                             */
/* -------------------------------------------------------------------------- */

// 当页面渲染完毕后马上调用下面的函数，这个函数是在当前页面 - 设置 - 生命周期 - 页面加载完成时中被关联的。
export function didMount() {
  console.log(`「页面 JS」：当前页面地址 ${location.href}`);
  // console.log(`「页面 JS」：当前页面 id 参数为 ${this.state.urlParams.id}`);
  // 更多 this 相关 API 请参考：https://www.yuque.com/yida/support/ocmxyv#OCEXd
  // document.title = window.loginUser.userName + ' | 宜搭';
}

</code></pre>
<h3>子表值变更事件处理函数模板</h3>
<p>监听子表值变更，根据引起变更的原因执行不同的处理逻辑是一个较普遍的需求。这个模板罗列了大部分引起子表变更的原因，根据需求删除不需要的分支即可。</p>
<pre class="prettyprint source lang-Javascript"><code>/**
 * 子表数据变更事件模板
 * @param {object} param0
 */
export function onSubformChange({ extra }) {
  if (!extra) {
    // TODO: 当通过JS设置子表数据时执行
  }
  if (extra && extra.from === &quot;add_item&quot;) {
    // TODO: 当点击子表新增按钮时执行
  }
  if (extra && extra.from === &quot;del_item&quot;) {
    // TODO: 当点击子表删除按钮时执行
  }
  if (extra && extra.from === &quot;copy_item&quot;) {
    // TODO: 当点击子表复制按钮时执行
  }
  if (extra && extra.from === &quot;form_change&quot;) {
    // TODO: 当子表某个字段值变更时执行

    if (extra.fieldId === &quot;textField_xxxxxx&quot;) {
      // TODO: 匹配特定字段值变更时执行
    }
  }
}
</code></pre>
<h3>提交前校验事件模板</h3>
<p>在一些复杂业务场景中可能需要编写 JS 在表单提交前实现一些复杂的校验，这些校验往往包含一些异步的操作，比如需要请求另外一个表单的数据来进行计算比对，并且显示自定义提示内容。此模板提供了对这类场景的最佳处理方法。</p>
<pre class="prettyprint source lang-jsx"><code>/**
 * async/await风格的校验函数
 * @param {Object} context this上下文
 */
async function validateA(context) {
  let valid = false;

  // TODO: 校验逻辑

  if (valid) {
    // 校验通过，直接return
    return;
  } else {
    // 校验不通过
    // 可以 throw 一个字符串
    throw &quot;xxxx不一致，校验失败&quot;;
    // 一个 jsx
    throw (
      &lt;div style={{ color: &quot;red&quot;, fontSize: &quot;18px&quot; }}>xxxx不一致，校验失败&lt;/div>
    );
    // 一个 Error
    throw Error(&quot;xxxx不一致，校验失败&quot;);
    // 或者一个字符串数组，适用于需要对子表进行校验的场景
    throw [
      &quot;子表中的以下数据校验失败&quot;,
      &quot;第 1 条数据，xxx和xxx不匹配&quot;,
      &quot;第 2 条数据，缺少xxx&quot;,
    ];
  }
}

async function validateB(context) {
  // TODO: 校验逻辑同validateA
}

/**
 * 提交前校验，校验过程支持异步操作。
 * 本示例中有两个校验，校验A和校验B,均包含异步操作。校验A、B按顺序执行，即A校验执行完后才会执行B校验。
 * 如果校验A未通过则显示错误提示信息，并不会执行校验B。
 * @returns {Promise}
 */
export function beforeSubmit() {
  return Promise.resolve()
    .then(() => {
      // 校验A
      return validateA(this);
    })
    .then(() => {
      // 校验B
      return validateB(this);
    })
    .catch((e) => {
      // 校验失败将执行这里的逻辑来显示错误提示信息。
      let message = e instanceof Error ? e.message : e;
      message = message || &quot;校验失败&quot;;

      let jsx = &quot;&quot;;
      if (Array.isArray(message)) {
        jsx = (
          &lt;p>
            {message.map((msg) => (
              &lt;p>{msg}&lt;/p>
            ))}
          &lt;/p>
        );
      } else {
        jsx = message;
      }

      this.utils.dialog({
        method: &quot;alert&quot;,
        title: &quot;校验失败&quot;,
        content: jsx,
      });

      throw e;
    });
}
</code></pre></article>
    </section>






    
    
</div>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Tue Mar 19 2024 17:01:50 GMT+0800 (中国标准时间) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>

<script src="scripts/search.js" defer></script>



</body>
</html>